unit HeapSortVision;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Math, StdCtrls;

type
  Cor=record
    x, y: integer;
  end;
  TForm1 = class(TForm)
    Timer1: TTimer;
    Timer2: TTimer;
    Timer3: TTimer;
    Timer4: TTimer;
    ScrollBar1: TScrollBar;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Timer3Timer(Sender: TObject);
    procedure Timer4Timer(Sender: TObject);
  private
    procedure Draw1(num:integer);
    procedure Draw2;
  public
    { Public declarations }
  end;                                    
const
  H=20;

var
  Form1: TForm1;
  xy: array of Cor;
  arr: array of integer;
  pan: array of TPanel;
  ans: array of TPanel;
  i, j, n, m, Fn: integer;
  k, v, r, p: integer;
  x0, q, a, b, t, num, cf: integer;
implementation

{$R *.dfm}

procedure TForm1.Draw1(num: integer);
begin
  for cf:=0 to n-1 do
    pan[cf].color:=clBtnFace;
  pan[num].Color:=clYellow;
  if (2*num+1<n) then
    pan[num*2+1].Color:=clYellow;
  if (2*num+2<n) then
    pan[num*2+2].Color:=clYellow;
end;

procedure TForm1.Draw2;
begin
  for cf:=0 to n-1 do
    pan[cf].color:=clBtnFace;
  pan[0].Color:=clRed;
  pan[n-1].Color:=clRed;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  n:=9;
  setlength(arr, n);
  setlength(pan, n);
  setlength(xy, n);
  setlength(ans, n);
  if (n=1) then
  begin
    pan[0]:=TPanel.Create(Form1);
    pan[0].Parent:=Form1;
    pan[0].Height:=100;
    pan[0].Width:=100;
    pan[0].Top:=230;
    pan[0].Left:=470;
    pan[0].Caption:=inttostr(random(50));
  end else begin
    v:=1;
    m:=0;
    for i:=0 to n-1 do
    begin
      arr[i]:=random(100);
    end;
    while (n>=v) do
    begin
      v:=v*2;
      m:=m+1;
    end;
    p:=floor(Form1.height div (v div 2));
    r:=floor((p-H) div 2);
    v:=1;
    q:=0;
    for i:=0 to m-1 do
    begin
      x0:=floor(Form1.Width div (v*2));
      xy[q].x:=x0;
      xy[q].y:=p*i+floor(p div 2);
      q:=q+1;
      while (q<v*2-1) and (q<n) do
      begin
        xy[q].x:=xy[q-1].x+2*x0;
        xy[q].y:=xy[q-1].y;
        q:=q+1;
      end;
      v:=v*2;
    end;
    for i:=0 to n-1 do
    begin
      pan[i]:=TPanel.Create(Form1);
      pan[i].Parent:=Form1;
      pan[i].Height:=2*r;
      pan[i].Width:=2*r;
      pan[i].Top:=xy[i].y-r;
      pan[i].Left:=xy[i].x-r;
      pan[i].Caption:=inttostr(arr[i]);
    end;
    i:=n;
    Fn:=n;
    timer1.enabled:=true;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  timer1.Enabled:=false;
  timer2.Enabled:=true;
  i:=i-1;
  num:=i;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin

  for j:=0 to n-1 do
    pan[j].Caption:=inttostr(arr[j]);
  Draw1(num);

  a:=2000000000;
  b:=2000000000;
  if (2*num+1<n) then
    a:=arr[2*num+1];
  if (2*num+2<n) then
    b:=arr[2*num+2];
  if (a<=b) and (a<arr[num]) then
  begin
    t:=arr[2*num+1];
    arr[2*num+1]:=arr[num];
    arr[num]:=t;
    num:=2*num+1;
  end else if (b<=a) and (b<arr[num]) then
  begin
    t:=arr[2*num+2];
    arr[2*num+2]:=arr[num];
    arr[num]:=t;
    num:=2*num+2;
  end else begin
    timer2.Enabled:=false;
    timer1.Enabled:=true;
    if (i=0) then
    begin
      timer1.Enabled:=false;
      i:=0;
      j:=0;
      for cf:=0 to n-1 do
        pan[cf].color:=clBtnFace;
      timer3.enabled:=true;
    end;
  end;

  sleep(Scrollbar1.position);

end;

procedure TForm1.Timer3Timer(Sender: TObject);
begin
  Draw2;
  t:=arr[0];
  arr[0]:=arr[n-1];
  arr[n-1]:=t;
  n:=n-1;
  i:=i+1;
  num:=0;
  timer3.Enabled:=false;
  timer4.Enabled:=true;
end;

procedure TForm1.Timer4Timer(Sender: TObject);
begin

  sleep(2*scrollbar1.Position);
  for j:=0 to Fn-1 do
    pan[j].Caption:=inttostr(arr[j]);
  Draw1(num);

  a:=2000000000;
  b:=2000000000;
  if (2*num+1<n) then
    a:=arr[2*num+1];
  if (2*num+2<n) then
    b:=arr[2*num+2];
  if (a<=b) and (a<arr[num]) then
  begin
    t:=arr[2*num+1];
    arr[2*num+1]:=arr[num];
    arr[num]:=t;
    num:=2*num+1;
  end else if (b<=a) and (b<arr[num]) then
  begin
    t:=arr[2*num+2];
    arr[2*num+2]:=arr[num];
    arr[num]:=t;
    num:=2*num+2;
  end else begin
    timer4.Enabled:=false;
    timer3.Enabled:=true;
    ans[i-1]:=TPanel.Create(Form1);
    ans[i-1].Parent:=Form1;
    ans[i-1].Height:=70;
    ans[i-1].Width:=70;
    ans[i-1].Top:=form1.Height-200;
    ans[i-1].Left:=50+70*(i-1);
    ans[i-1].Caption:=inttostr(arr[n]);
    if (i=Fn-1) then
    begin
      pan[0].Color:=clRed;
      timer3.Enabled:=false;
      timer4.enabled:=false;
      ans[Fn-1]:=TPanel.Create(Form1);
      ans[Fn-1].Parent:=Form1;
      ans[Fn-1].Height:=70;
      ans[Fn-1].Width:=70;
      ans[Fn-1].Top:=form1.Height-200;
      ans[Fn-1].Left:=50+70*(Fn-1);
      ans[Fn-1].Caption:=inttostr(arr[0]);
    end;
  end;
  sleep(scrollbar1.Position);
end;

end.
